package com.library.uiframework.fragment.ptr;

import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.library.uiframework.R;
import com.library.uiframework.fragment.StateViewFragment;
import com.library.uiframework.mvp.IPageLifecycle;
import com.library.uiframework.mvp.PagingDataLoadPresenter;
import com.library.uiframework.mvp.PagingDataLoadView;
import com.library.uiframework.widget.state.StateView;
import com.library.xtype.IAdapter;
import com.library.xtype.NuwaRecyclerViewAdapter;
import in.srain.cube.views.ptr.PtrClassicFrameLayout;
import in.srain.cube.views.ptr.PtrFrameLayout;

/**
 * @author hongkai.qian
 * @version 1.0.0
 * @since 17/3/17
 */
abstract public class PagingRecyclerViewFragment<VIEW extends PagingDataLoadView> extends StateViewFragment
    implements PagingDataLoadView, PtrViewHelper.OnPtrHandlerListener {

    private static final String TAG = "RecyclerViewList";

    private PtrClassicFrameLayout mPtrFrameLayout;

    private RecyclerView mRecyclerView;

    private IAdapter mAdapter;

    private PagingDataLoadPresenter<VIEW> mPresenter;

    protected int listViewLayoutId() {
        return needPtrAndLoadNextFeature() ? R.layout.uiframework_recyclerview_with_ptr
            : R.layout.uiframework_recyclerview_without_ptr;
    }

    /**
     * @return 实现IPagingListAdapter接口, 同时需要派生自RecyclerView.Adapter
     * <p>
     * 可选择 NuwaRecyclerViewAdapter 或者 PagingRecyclerViewAdapter 的派生类
     */
    protected abstract IAdapter onCreateAdapter();

    /**
     * 给业务一个加工contentView的机会, 比如再包装一层
     *
     * @param contentView contentView
     * @return contentView
     */
    protected View onContentViewInflated(View contentView) {
        return contentView;
    }

    protected abstract PagingDataLoadPresenter<VIEW> onCreatePresenter();

    protected boolean needPtrAndLoadNextFeature() {
        return true;
    }

    protected LayoutManager onCreateLayoutManager(Context context) {
        return new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
    }

    @Override
    protected View onCreateContentView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
        View mainView = layoutInflater.inflate(listViewLayoutId(), viewGroup, false);

        mRecyclerView = (RecyclerView)mainView.findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(onCreateLayoutManager(layoutInflater.getContext()));

        mRecyclerView.setHasFixedSize(true);

        mAdapter = onCreateAdapter();
        RecyclerView.Adapter adapter = (RecyclerView.Adapter)mAdapter;
        mRecyclerView.setAdapter(adapter);
        if (needPtrAndLoadNextFeature()) {
            mPtrFrameLayout = (PtrClassicFrameLayout)mainView.findViewById(R.id.ptr_frame_layout);
            new PtrViewHelper(mPtrFrameLayout, this);
        }
        return onContentViewInflated(mainView);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        mPresenter = onCreatePresenter();
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    protected void registerPageLifecycles() {
        super.registerPageLifecycles();
        if (mPresenter != null) {
            registerPageLifecycle(mPresenter);
        }
        if (mAdapter instanceof NuwaRecyclerViewAdapter) {
            final NuwaRecyclerViewAdapter adapter = (NuwaRecyclerViewAdapter)mAdapter;
            registerPageLifecycle(new IPageLifecycle() {
                @Override
                public void onCreate() {
                    adapter.onCreate();
                }

                @Override
                public void onStart() {
                    adapter.onStart();
                }

                @Override
                public void onResume() {
                    adapter.onResume();
                }

                @Override
                public void onPause() {
                    adapter.onPause();
                }

                @Override
                public void onStop() {
                    adapter.onStart();
                }

                @Override
                public void onDestroy() {
                    adapter.onDestroy();
                }
            });
        }
    }

    @Override
    public void onLoadFinished() {
        super.onLoadFinished();
        if (enterAutoLoading()) {
            mPresenter.reload(false);
        }
    }

    protected boolean enterAutoLoading() {
        return true;
    }

    @Override
    protected final StateView.State originalState() {
        return enterAutoLoading() ? StateView.State.LOADING : StateView.State.SUCCESS;
    }

    @Override
    protected void onRetryRequested() {
        mPresenter.reload(false);
    }

    /**
     * 吸收listview换成recyclerView的经验教训, 此方法如无必要尽量不要调用
     * 主要便于将来更换成其他更牛逼的XxxxView使业务无感
     * 如果觉得想要进行的操作比较通用, 可提出来放到基类支持
     *
     * @return 当前页面的RecyclerView
     */
    protected RecyclerView getRecyclerView() {
        return mRecyclerView;
    }

    protected void refreshComplete() {
        if (mPtrFrameLayout != null) {
            mPtrFrameLayout.refreshComplete();
        }
    }

    @Override
    public void flushData(List dataList) {
        mAdapter.flushData(dataList);
    }

    @Override
    public void appendData(List dataList) {
        mAdapter.appendData(dataList);
    }

    @Override
    public void showNextPageLoading() {
        //        mFooterView.setState(LoadingFooterView.State.Loading);
    }

    @Override
    public void showNextPageFailure() {
        refreshComplete();
    }

    @Override
    public void showNextPageSuccess() {
        refreshComplete();
    }

    @Override
    public void showAllPageLoaded() {
        //mRecyclerView.setNoMore(true);
    }

    @Override
    public void showLoading() {
        setState(StateView.State.LOADING);
    }

    @Override
    public void showFailure(String message) {
        refreshComplete();
        setState(StateView.State.FAILED);
    }

    @Override
    public void showNoData() {
        refreshComplete();
        setState(StateView.State.NO_DATA);
    }

    @Override
    public void showSuccess() {
        refreshComplete();
        setState(StateView.State.SUCCESS);
    }

    @Override
    public boolean isDataEmpty() {
        return mAdapter == null || mAdapter.getRealCount() <= 0;
    }

    @Override
    public void onLoadMoreBegin(PtrFrameLayout frameLayout) {
        mPresenter.loadNextPage();
    }

    @Override
    public void onRefreshBegin(PtrFrameLayout frameLayout) {
        mPresenter.reload();
    }

    @Override
    public boolean onInterceptLoadMore() {
        return false;
    }

    @Override
    public boolean onInterceptRefresh() {
        return false;
    }
}
